Update README.md
[BattleCats.git] / Assets / EZ Object Pools / Scripts / EZObjectPool.cs
blobfe05d4b9d3544670051e5f65c2355ca9f82d6758
1 using UnityEngine;
2 using System.Collections.Generic;
4 namespace EZObjectPools
6 [AddComponentMenu("EZ Object Pool/Object Pool")]
7 public class EZObjectPool : MonoBehaviour
9 static Dictionary<string, EZObjectPool> SharedPools = new Dictionary<string, EZObjectPool>();
10 static GameObject Marker;
12 /// <summary>
13 /// The template GameObject this pool uses.
14 /// </summary>
15 public GameObject Template;
16 /// <summary>
17 /// The name of this pool.
18 /// </summary>
19 public string PoolName;
20 /// <summary>
21 /// The list of all objects owned by this pool.
22 /// </summary>
23 public List<GameObject> ObjectList;
24 /// <summary>
25 /// Should this pool automatically resize when empty?
26 /// </summary>
27 public bool AutoResize = false;
28 /// <summary>
29 /// The default pool size.
30 /// </summary>
31 public int PoolSize = 100;
32 /// <summary>
33 /// Only used for pools created in the editor. Should this pool be instantiated when the scene loads?
34 /// </summary>
35 public bool InstantiateOnAwake;
36 /// <summary>
37 /// Only used for pools created in the editor. Any scripts that request a pool with the same name as this one will recieve this pool.
38 /// </summary>
39 public bool Shared;
41 /// <summary>
42 /// Creates a new Object Pool and returns a reference to the created pool.
43 /// </summary>
44 /// <param name="template">The template this pool will make copies of.</param>
45 /// <param name="name">The name of this pool. Only used to identify it in the hierarchy.</param>
46 /// <param name="size">How many objects will be pre-instantiated.</param>
47 /// <param name="autoResize">Should this pool create new objects if it is empty?</param>
48 /// <param name="instantiateImmediate">Should this pool be instantiated immediately?</param>
49 /// <param name="shared">Should pools with the same name be shared?</param>
50 /// <returns>A reference to the created pool.</returns>
51 public static EZObjectPool CreateObjectPool(GameObject template, string name, int size, bool autoResize, bool instantiateImmediate, bool shared)
53 if (Marker == null)
55 Marker = new GameObject("EZ Object Pools Container");
56 SharedPools.Clear();
59 if (shared)
61 if (SharedPools.ContainsKey(name))
62 return SharedPools[name];
63 else
65 GameObject g = new GameObject(name);
66 EZObjectPool pool = g.AddComponent<EZObjectPool>();
67 pool.InstantiateOnAwake = false;
68 pool.SetProperties(template, size, name, autoResize);
69 SharedPools.Add(name, pool);
71 if (instantiateImmediate)
72 pool.InstantiatePool();
74 g.transform.parent = Marker.transform;
76 return pool;
79 else
81 GameObject g = new GameObject(name);
82 EZObjectPool pool = g.AddComponent<EZObjectPool>();
83 pool.InstantiateOnAwake = false;
84 pool.SetProperties(template, size, name, autoResize);
86 if (instantiateImmediate)
87 pool.InstantiatePool();
89 g.transform.parent = Marker.transform;
91 return pool;
95 void Awake()
97 if (Marker == null)
99 Marker = new GameObject("EZ Object Pools Container");
100 SharedPools.Clear();
103 if (InstantiateOnAwake)
105 ObjectList = new List<GameObject>(PoolSize);
106 AvailableObjects = new List<GameObject>(PoolSize);
107 InstantiatePool();
110 if (Shared)
112 SharedPools.Add(this.PoolName, this);
116 #region Instance Functions
118 List<GameObject> AvailableObjects;
120 /// <summary>
121 /// Set the properties of the pool.
122 /// </summary>
123 /// <param name="objectTemplate">The template object to clone.</param>
124 /// <param name="size">The amount of clones to create</param>
125 /// <param name="name">Name of this pool</param>
126 /// <param name="autoResize">Should new objects be instantiated if the pool is empty?</param>
127 public void SetProperties(GameObject objectTemplate, int size, string name, bool autoResize)
129 Template = objectTemplate;
130 PoolSize = size;
131 ObjectList = new List<GameObject>(size);
132 AvailableObjects = new List<GameObject>(size);
133 PoolName = name;
134 this.AutoResize = autoResize;
137 /// <summary>
138 /// Creates the set number of objects at the world origin (0,0,0) and sets them to inactive. Deletes any previous objects.
139 /// </summary>
140 public void InstantiatePool()
142 if (Template == null)
144 Debug.LogError("EZ Object Pool: " + name + ": Template GameObject is null! Make sure you assigned a template either in the inspector or in your scripts.");
145 return;
148 ClearPool();
150 for (int i = 0; i < PoolSize; i++)
152 GameObject g = NewActiveObject();
153 g.SetActive(false);
154 ObjectList.Add(g);
158 /// <summary>
159 /// Attempts to get the next available object in the pool. Will return true and assign a reference to the out variable if successful.
160 /// </summary>
161 /// <param name="pos">The position to spawn the object at.</param>
162 /// <param name="rot">The rotation to spawn the object at.</param>
163 /// <param name="obj">A reference to the GameObject being spawned.</param>
164 /// <returns>Returns true if an object was successfully retrieved, False if not.</returns>
165 public bool TryGetNextObject(Vector3 pos, Quaternion rot, out GameObject obj)
167 if (ObjectList.Count == 0)
169 Debug.LogError("EZ Object Pool " + PoolName + ", the pool has not been instantiated but you are trying to retrieve an object!");
172 int lastIndex = AvailableObjects.Count - 1;
174 if (AvailableObjects.Count > 0)
176 if (AvailableObjects[lastIndex] == null)
178 Debug.LogError("EZObjectPool " + PoolName + " has missing objects in its pool! Are you accidentally destroying any GameObjects retrieved from the pool?");
179 obj = null;
180 return false;
183 AvailableObjects[lastIndex].transform.position = pos;
184 AvailableObjects[lastIndex].transform.rotation = rot;
185 AvailableObjects[lastIndex].SetActive(true);
186 obj = AvailableObjects[lastIndex];
187 AvailableObjects.RemoveAt(lastIndex);
188 return true;
191 if (AutoResize)
193 GameObject g = NewActiveObject();
194 g.transform.position = pos;
195 g.transform.rotation = rot;
196 ObjectList.Add(g);
197 obj = g;
198 return true;
200 else
202 obj = null;
203 return false;
207 /// <summary>
208 /// Attempts to get the next available object in the pool. Will do nothing if the pool is empty.
209 /// </summary>
210 /// <param name="pos">The position to put the object at.</param>
211 /// <param name="rot">The rotation to put the object at.</param>
212 public void TryGetNextObject(Vector3 pos, Quaternion rot)
214 if (ObjectList.Count == 0)
216 Debug.LogError("EZ Object Pool " + PoolName + ", the pool has not been instantiated but you are trying to retrieve an object!");
219 int lastIndex = AvailableObjects.Count - 1;
221 if (AvailableObjects.Count > 0)
223 if (AvailableObjects[lastIndex] == null)
225 Debug.LogError("EZObjectPool " + PoolName + " has missing objects in its pool! Are you accidentally destroying any GameObjects retrieved from the pool?");
226 return;
229 AvailableObjects[lastIndex].transform.position = pos;
230 AvailableObjects[lastIndex].transform.rotation = rot;
231 AvailableObjects[lastIndex].SetActive(true);
232 AvailableObjects.RemoveAt(lastIndex);
233 return;
236 if (AutoResize)
238 GameObject g = NewActiveObject();
239 g.transform.position = pos;
240 g.transform.rotation = rot;
241 ObjectList.Add(g);
245 GameObject NewActiveObject()
247 GameObject g = (GameObject)Instantiate(Template);
248 g.transform.parent = transform;
250 PooledObject p = g.GetComponent<PooledObject>();
252 if (p)
253 p.ParentPool = this;
254 else
255 g.AddComponent<PooledObject>().ParentPool = this;
257 return g;
260 /// <summary>
261 /// Destroys all objects that are a part of this pool.
262 /// </summary>
263 public void ClearPool()
265 for (int i = 0; i < ObjectList.Count; i++)
267 Destroy(ObjectList[i]);
270 ObjectList.Clear();
271 AvailableObjects.Clear();
274 /// <summary>
275 /// Destroys this pool.
276 /// </summary>
277 /// <param name="deleteActiveObjects">Should it delete any active GameObjects that are part of this pool?</param>
278 public void DeletePool(bool deleteActiveObjects)
280 for (int i = 0; i < ObjectList.Count; i++)
282 if (!ObjectList[i].activeInHierarchy || (ObjectList[i].activeInHierarchy && deleteActiveObjects))
283 Destroy(ObjectList[i]);
287 /// <summary>
288 /// Adds the given GameObject to the Available Objects list.
289 /// </summary>
290 /// <param name="obj">The GameObject to add.</param>
291 public void AddToAvailableObjects(GameObject obj)
293 AvailableObjects.Add(obj);
296 #endregion
298 #region Statistics
300 /// <summary>
301 /// Gets the number of currently active objects.
302 /// </summary>
303 public int ActiveObjectCount()
305 return ObjectList.Count - AvailableObjects.Count;
308 /// <summary>
309 /// Gets the number of currently available objects.
310 /// </summary>
311 public int AvailableObjectCount()
313 return AvailableObjects.Count;
316 #endregion